package xyz.xtt.common.response;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import lombok.Builder;
import lombok.Data;
import xyz.xtt.common.exception.NftException;

/**
 * 统一返回类
 * 
 * @author huqibo
 * @date 2024/11/11
 */
@Builder
@Data
public class ApiResult<T> implements Serializable {

	private static final long serialVersionUID = 1L;

	public static final int SUCCESS = 0;

	private int code;

	private String msg;

	private T data;

	public ApiResult() {

	}

	public ApiResult(T data) {
		this.code = SUCCESS;
		this.msg = "OK";
		this.data = data;
	}

	public ApiResult(Integer status, String msg, T data) {
		this.code = status;
		this.msg = msg;
		this.data = data;
	}

	public static <T> ApiResult<T> ok() {
		return new ApiResult<>(null);
	}

	public static <T> ApiResult<T> ok(T data) {
		return new ApiResult<>(data);
	}

	public static ApiResult<Void> failure(NftException e) {
		return new ApiResult<>(e.getCode(), e.getMessage(), null);
	}

	public static <T> ApiResult<T> failure() {
		return new ApiResult<>(-1, "fallback", null);
	}

	public static <T> ApiResult<T> build(Integer status, String msg) {
		return new ApiResult<>(status, msg, null);
	}

	public static <T> ApiResult<T> failure(Integer status, String msg) {
		return new ApiResult<>(status, msg, null);
	}

	public static <T> ApiResult<T> build(Integer status, String msg, T data) {
		return new ApiResult<>(status, msg, data);
	}

	public boolean isOk() {
		return Objects.equals(0, code);
	}

	public static <T> T convertObj(ApiResult<T> result) {
		T info = Optional.ofNullable(result).filter(ApiResult::isOk).map(ApiResult::getData).orElse(null);
		return info;
	}

	public static <T> List<T> convertList(ApiResult<List<T>> result) {
		List<T> list = Optional.ofNullable(result).filter(ApiResult::isOk).map(ApiResult::getData).orElse(new ArrayList<T>());
		return list;
	}

	public static <T> T convert(ApiResult<T> result, T defalut) {
		T t = Optional.ofNullable(result).filter(ApiResult::isOk).map(ApiResult::getData).filter(Objects::nonNull).orElse(defalut);
		return t;
	}
}
